#pragma once

#include <AVUIAnimatable.h>

namespace AVUI {

class IClientImageSource;
class Uri;

class BitmapImage : public Animatable
{
    friend class ImageBrush;
    friend class ShaderEffect;
public:

    DECLARE_ELEMENT(BitmapImage, Animatable);

    DECLARE_DEPENDENCY_PROPERTY(CacheOption);
    BitmapCacheOption::Enum get_CacheOption() { return (BitmapCacheOption::Enum)(AVUI::UnboxValue<int>(GetValue(get_CacheOptionProperty()))); }
    void set_CacheOption(BitmapCacheOption::Enum value) { SetValue(get_CacheOptionProperty(), AVUI::BoxValue<int>(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(CreateOptions);
    BitmapCreateOptions::Enum get_CreateOptions() { return (BitmapCreateOptions::Enum)(AVUI::UnboxValue<int>(GetValue(get_CreateOptionsProperty()))); }
    void set_CreateOptions(BitmapCreateOptions::Enum value) { SetValue(get_CreateOptionsProperty(), AVUI::BoxValue<int>(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(UriSource);
    TRefCountedPtr<Uri> get_UriSource() { return (Uri*)GetValue(get_UriSourceProperty()).get_Ptr(); }
    void set_UriSource(Uri* pValue) { SetValue(get_UriSourceProperty(), (Object*) pValue); }

    void add_DownloadCompleted(AVUI::EventHandler* pValue) { AddEventHandler(get_DownloadCompletedEvent(), (AVUI::Delegate*)pValue); }
    void remove_DownloadCompleted(AVUI::EventHandler* pValue) { RemoveEventHandler(get_DownloadCompletedEvent(), (AVUI::Delegate*)pValue); }
    DECLARE_EVENT(DownloadCompleted);

    void add_DownloadProgress(AVUI::EventHandler* pValue) { AddEventHandler(get_DownloadProgressEvent(), (AVUI::Delegate*)pValue); }
    void remove_DownloadProgress(AVUI::EventHandler* pValue) { RemoveEventHandler(get_DownloadProgressEvent(), (AVUI::Delegate*)pValue); }
    DECLARE_EVENT(DownloadProgress);

    void add_DownloadFailed(AVUI::EventHandler* pValue) { AddEventHandler(get_DownloadFailedEvent(), (AVUI::Delegate*)pValue); }
    void remove_DownloadFailed(AVUI::EventHandler* pValue) { RemoveEventHandler(get_DownloadFailedEvent(), (AVUI::Delegate*)pValue); }
    DECLARE_EVENT(DownloadFailed);

    BitmapImage() : m_pClientImageSource(NULL) { };
    BitmapImage(Uri* pUri) : m_pClientImageSource(NULL) { set_UriSource(pUri); }
    ~BitmapImage();

    float get_Width();
    float get_Height();



protected:

    virtual TRefCountedPtr<Freezable> CreateInstanceCore() AVUI_OVERRIDE { return object_allocate<BitmapImage>().get_Ptr(); }

private:
    static void StaticConstructor();

    void OnClientDownloadCompleted(Object* pSender, EventArgs* pArgs);
    void OnClientDownloadProgress(Object* pSender, EventArgs* pArgs);
    void OnClientDownloadFailed(Object* pSender, EventArgs* pArgs);

    IClientImageSource* get_ClientImageSource() { return m_pClientImageSource; }

    static void UriSourcePropertyChanged(DependencyObject* pDO, DependencyPropertyChangedEventArgs* e);

    IClientImageSource* m_pClientImageSource;
};

class BitmapImageTypeConverter : public TypeConverter
{
    virtual bool CanConvertFrom(Object* pContext, const Type& type) const;
    virtual ObjectPtr ConvertFrom(Object* pContext, Object* pObjectFrom) const;
    virtual bool CanConvertTo(Object* pContext, const Type& type) const { return false; };
    virtual ObjectPtr ConvertTo(Object* pContext, Object* pObjectFrom, const Type& type) const { LibraryCriticalError(); return NULL; }
};


}; // namespace AVUI

